﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using umbraco;
using umbraco.NodeFactory;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.web;
using System.Xml;

namespace ScDataTypes.DataTypes
{

    [ToolboxData("<{0}:ContentTreeviewDropDownList runat=server></{0}:ContentTreeviewDropDownList>")]
    public class ContentTreeviewDropDownList : BaseTreeviewDropDownListControl
    {

        #region Variables

        bool _DocumentChildren = true;
       
        #endregion

        #region Properties

        /// <summary>
        /// Comma seperated string containing the numberic ids of all selected nodes value1,value2,value3
        /// </summary>
        public new string Selected
        {
            get
            {
                return base.Selected;
            }
            set
            {
                // Ensure controls are created
                this.EnsureChildControls();

                // Loop through all node ids
                this.AddDocument(value);
            }
        }

        /// <summary>
        /// Allowed document types
        /// </summary>
        public string DocumentType
        {
            get { return this.ToStr(ViewState["DocumentType"]); }
            set { ViewState["DocumentType"] = value; }
        }

        /// <summary>
        /// Current document id
        /// </summary>
        public int DocumentId { get { return ToInt(this.Page.Request.QueryString["id"]); } }

        /// <summary>
        /// Inital path to the root node
        /// </summary>
        public string Location
        {
            get { return this.ToStr(ViewState["Location"]); }
            set { ViewState["Location"] = value; }
        }

        /// <summary>
        /// Are child nodes allowed to be viewied
        /// </summary>
        public string DocumentChildren
        {
            set { _DocumentChildren = Convert.ToBoolean(Math.Abs(ToInt(value))); }
            get { return Math.Abs(Convert.ToInt32(this._DocumentChildren)).ToString(); }
        }

        #endregion

        #region Document Functions

        /// <summary>
        ///  Get the initial starting node
        /// </summary>
        /// <returns></returns>
        Document[] GetInitalDocuments()
        {
            try
            {
                // Get inital node
                if (this.Location.Length != 0)
                    if (umbraco.helper.IsNumeric(this.Location))
                    {
                        Document objDocument = new Document(Convert.ToInt32(this.Location));
                        if (objDocument != null && objDocument.Id == Convert.ToInt32(this.Location))
                            return new Document[] { objDocument };
                    }
                    else
                    {
                        Document objDocument;
                        string[] strLocation = this.Location.Split("/".ToCharArray());

                        // Get the base documemt to path search on
                        if (this.Location.StartsWith("/"))
                            objDocument = Document.GetRootDocuments()[0];
                        else
                            objDocument = new Document(Convert.ToInt32(this.DocumentId));

                        //  Loop through the entire path an find the correct document
                        if (this.Location.Trim().Length != 0)
                        {
                            foreach (string PathItem in strLocation)
                                if (PathItem == "..")
                                    objDocument = new Document(objDocument.ParentId);
                                else
                                    foreach (Document objChildDocuments in objDocument.Children)
                                        if (string.Compare(objChildDocuments.Text, PathItem, true) == 0)
                                        {
                                            objDocument = objChildDocuments;
                                            break;
                                        }

                            return objDocument.Children;
                        }
                    }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.ToString());
            }

            return Document.GetRootDocuments();
        }

        /// <summary>
        /// Add node to selected listbox providing it doesn't already exist
        /// </summary>
        /// <param name="NodeId">String containing the numberic node id</param>
        void AddDocument(string DocumentId)
        {
            try
            {
                if (umbraco.helper.IsNumeric(DocumentId))
                {
                    if (DocumentId == "0")
                    {
                        base.TextBox.Text = string.Empty;
                        base.Selected = string.Empty;
                    }
                    else
                    {
                        // Find node in umbraco and add to listbox from the database to ignore issues with
                        // unpublished nodes
                        Document objDocument = new Document(Convert.ToInt32(DocumentId));

                        if ((objDocument != null && objDocument.Id != 0) &&
                            (
                                this.DocumentType == string.Empty || string.Compare(this.DocumentType, objDocument.ContentType.Alias) == 0
                            ))
                        {
                            base.Selected = objDocument.Id.ToString();
                            base.TextBox.Text = objDocument.Text;
                        }
                    }
                }
            }
            catch
            {
            }
        }

        #endregion

        #region TreeView Functions

        /// <summary>
        /// Populate treenode event
        /// </summary>
        protected override void PopulateTreeView(TreeNodeEventArgs e)
        {
            Document objDocument = new Document(Convert.ToInt32(e.Node.Value));

            // Check for child nodes
            if (objDocument != null &&
                objDocument.Id != 0 &&
                objDocument.ChildCount != 0)
                this.PopulateTreeviewFromDocument(e.Node, objDocument);
        }

        /// <summary>
        /// Populate nodes on a TreeNode my matching it to the Node.Children
        /// </summary>
        /// <param name="TreeNode">TreeNode that requires to be populated</param>
        /// <param name="Node">Node to use to copy Node.Children from</param>
        void PopulateTreeviewFromDocument(TreeNode TreeNode, Document Document)
        {
            foreach (Document objDocument in Document.Children)
            {
                TreeNode objTreeNode = new TreeNode();

                // Node properties
                objTreeNode.Text = objDocument.Text;
                objTreeNode.Value = objDocument.Id.ToString();
                objTreeNode.Expanded = false;

                // Expanding nodes
                if (objDocument.ChildCount != 0)
                    objTreeNode.PopulateOnDemand = true;
                else
                    objTreeNode.PopulateOnDemand = false;

                // Image
                if (objDocument.ContentType.IconUrl.StartsWith("."))
                    objTreeNode.ImageUrl = ImagePath + "folder.gif";
                else
                    objTreeNode.ImageUrl = ImagePath + objDocument.ContentType.IconUrl;

                // Add treenode
                TreeNode.ChildNodes.Add(objTreeNode);
            }
        }

        #endregion

        #region Child Controls

        /// <summary>
        /// Child control all created and treeview setup
        /// </summary>
        protected override void ChildControlsCreated()
        {
            this.SelectionChanged += new SelectionChangedDelegate(ContentTreeviewDropDownList_SelectionChanged);

            if (!this.Page.IsPostBack)
            {
                // Inital node
                foreach (Document objDocument in Functions.GetDocumentFromPath(this.DocumentId, this.Location))
                {
                    // Setup node
                    TreeNode objTreeNode = new TreeNode();
                    objTreeNode.Text = (objDocument.Text != string.Empty && objDocument.Text != "-1" ? objDocument.Text : "Content");
                    objTreeNode.Value = objDocument.Id.ToString();
                    objTreeNode.ImageUrl = ImagePath + "folder.gif";
                    objTreeNode.Expanded = false;

                    // Add inital node children
                    if (this._DocumentChildren)
                        this.PopulateTreeviewFromDocument(objTreeNode, objDocument);

                    // Add root node to treeview
                    this.TreeView.Nodes.Add(objTreeNode);
                }
            }
        }

        #endregion

        #region Postback Events

        void ContentTreeviewDropDownList_SelectionChanged(object sender, EventArgs e)
        {
            this.AddDocument(this.TreeView.SelectedValue);
        }

        #endregion

    }

}
